#include <ShObjIdl.h>
//#include <objbase.h>
//#include <ShlGuid.h>
#include "ShellBrowser.h"
#include "ShellHelper.h"
#include "Macros.h"
//#include "CommDlgBrowser3.h"
CShellBrowser::CShellBrowser(HWND mainWnd)
: m_MainWnd(mainWnd)
, m_ulRef(0)
, m_hWnd(NULL)
, m_pShellView(NULL)
, m_currentFolder(NULL)
, m_pidl(NULL)
{
}


CShellBrowser::~CShellBrowser()
{
}

//com interface

// IUnknown methods  
STDMETHODIMP CShellBrowser::QueryInterface(REFIID riid, void **ppvObject)
{
	if (ppvObject == NULL)
		return E_POINTER;

	*ppvObject = NULL;

	if (IsEqualIID(riid, IID_IUnknown))
		*ppvObject = static_cast<IUnknown*>(static_cast<IShellBrowser*>(this));
	else if (IsEqualIID(riid, IID_IOleWindow))
		*ppvObject = static_cast<IOleWindow*>(this);
	//else if (IsEqualIID(riid, IID_IServiceProvider))
	//	*ppvObject = static_cast<IServiceProvider*>(this);
	else if (IsEqualIID(riid, IID_IShellBrowser))
		*ppvObject = static_cast<IShellBrowser*>(this);
	else if (IsEqualIID(riid, IID_ICommDlgBrowser))
		*ppvObject = static_cast<ICommDlgBrowser*>(this);
	
	/*else if (IsEqualIID(riid, IID_ICommDlgBrowser2))
		*ppvObject = static_cast<ICommDlgBrowser2*>(this);
	else if (IsEqualIID(riid, IID_ICommDlgBrowser3))
		*ppvObject = static_cast<ICommDlgBrowser3*>(this);*/
	else
		return E_NOINTERFACE;

	static_cast<IUnknown*>(*ppvObject)->AddRef();

	return S_OK;
}

STDMETHODIMP_(ULONG) CShellBrowser::AddRef(void)
{
	return ++m_ulRef;
}

STDMETHODIMP_(ULONG) CShellBrowser::Release(void)
{
	if (--m_ulRef == 0UL)
	{
		//m_pObject = NULL;
		//delete this;
		return 0UL;
	}

	return m_ulRef;
}

// IServiceProvider methods  
STDMETHODIMP CShellBrowser::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
{
	OutputDebugString(L"CShellBrowser::QueryService\n");
	if (ppvObject == NULL)
		return E_POINTER;

	if (IsEqualGUID(guidService, SID_SShellBrowser))
		return QueryInterface(riid, ppvObject);
	else if (IsEqualGUID(guidService, IID_INameSpaceTreeControl))
	{
		//return QueryInterface(riid, ppvObject);
	}
	return E_NOINTERFACE;
}

// IOleWindow methods  
STDMETHODIMP CShellBrowser::GetWindow(HWND *phwnd)
{
	OutputDebugString(L"CShellBrowser::GetWindow\n");
	*phwnd = m_MainWnd;
	return S_OK;
}

STDMETHODIMP CShellBrowser::ContextSensitiveHelp(BOOL fEnterMode)
{
	OutputDebugString(L"CShellBrowser::ContextSensitiveHelp\n");
	return E_NOTIMPL;
}
// *** ICommDlgBrowser methods ***
STDMETHODIMP CShellBrowser::OnDefaultCommand(THIS_ struct IShellView * ppshv)
{	//handle double click and ENTER key if needed
	OutputDebugString(L"CShellBrowser::OnDefaultCommand\n");
	return E_NOTIMPL;
}
STDMETHODIMP CShellBrowser::OnStateChange(THIS_ struct IShellView * ppshv, ULONG uChange)
{	//handle selection, rename, focus if needed
	OutputDebugString(L"CShellBrowser::OnStateChange\n");
	return E_NOTIMPL;
}
STDMETHODIMP CShellBrowser::IncludeObject(THIS_ struct IShellView * ppshv, LPCITEMIDLIST pidl)
{	//filter files if needed
	OutputDebugString(L"CShellBrowser::IncludeObject\n");
	return E_NOTIMPL;
}
// *** ICommDlgBrowser2 methods ***
STDMETHODIMP CShellBrowser::Notify(
	/* [in] */ __RPC__in_opt IShellView *ppshv,
	/* [in] */ DWORD dwNotifyType)
{
	OutputDebugString(L"CShellBrowser::Notify\n");
	return E_NOTIMPL;
}

STDMETHODIMP CShellBrowser::GetDefaultMenuText(
	/* [in] */ __RPC__in_opt IShellView *ppshv,
	/* [size_is][string][out] */ __RPC__out_ecount_full_string(cchMax) LPWSTR pszText,
	/* [in] */ int cchMax)
{
	OutputDebugString(L"CShellBrowser::GetDefaultMenuText\n");
	return E_NOTIMPL;
}

STDMETHODIMP CShellBrowser::GetViewFlags(
	/* [out] */ __RPC__out DWORD *pdwFlags)
{
	OutputDebugString(L"CShellBrowser::GetViewFlags\n");
	*pdwFlags = CDB2GVF_SHOWALLFILES | CDB2GVF_NOSELECTVERB | CDB2GVF_NOINCLUDEITEM;
	return S_OK;
	return E_NOTIMPL;
}
// *** ICommDlgBrowser3 methods ***
STDMETHODIMP CShellBrowser::OnColumnClicked(__RPC__in_opt IShellView *ppshv, int iColumn)
{
	OutputDebugString(L"CShellBrowser::OnColumnClicked\n");

	return E_NOTIMPL;
}
STDMETHODIMP CShellBrowser::GetCurrentFilter(__RPC__out_ecount_full_string(cchFileSpec) LPWSTR pszFileSpec, int cchFileSpec)
{

	OutputDebugString(L"CShellBrowser::GetCurrentFilter\n");
	return E_NOTIMPL;
}
STDMETHODIMP CShellBrowser::OnPreViewCreated(__RPC__in_opt IShellView *ppshv)
{

	OutputDebugString(L"CShellBrowser::OnPreViewCreated\n");
	return E_NOTIMPL;
}
// IShellBrowser methods  
STDMETHODIMP CShellBrowser::BrowseObject(PCUIDLIST_RELATIVE pidl, UINT wFlags)
{
	OutputDebugString(L"CShellBrowser::BrowseObject\n");
	TCHAR szPath[MAX_PATH];
	HRESULT hr = GetFolderPathForDisplay(pidl, szPath);
	OutputDebugString(szPath); OutputDebugString(L"\n");
	return E_NOTIMPL;
}

STDMETHODIMP CShellBrowser::EnableModelessSB(BOOL fEnable)
{
	OutputDebugString(L"CShellBrowser::EnableModelessSB\n");
	return E_NOTIMPL;
}

STDMETHODIMP CShellBrowser::GetControlWindow(UINT id, HWND *lphwnd)
{
	OutputDebugString(L"CShellBrowser::GetControlWindow\n");
	if (lphwnd == NULL)
		return E_POINTER;
	if (FCW_STATUS == id)
	{
		*lphwnd = m_MainWnd;
		return S_OK;
	}
	else if (FCW_TREE == id)
	{
		*lphwnd = m_MainWnd;
		return S_OK;
	}
	return S_OK;
}

STDMETHODIMP CShellBrowser::GetViewStateStream(DWORD grfMode, IStream **ppStrm)
{
	OutputDebugString(L"CShellBrowser::GetViewStateStream\n");
	return E_NOTIMPL;
}

STDMETHODIMP CShellBrowser::InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
{
	OutputDebugString(L"CShellBrowser::InsertMenusSB\n");
	return E_NOTIMPL;
}

STDMETHODIMP CShellBrowser::OnViewWindowActive(IShellView *ppshv)
{
	OutputDebugString(L"CShellBrowser::OnViewWindowActive\n");
	return E_NOTIMPL;
}

STDMETHODIMP CShellBrowser::QueryActiveShellView(IShellView **ppshv)
{
	OutputDebugString(L"CShellBrowser::QueryActiveShellView\n");
	m_pShellView->AddRef();
	*ppshv = m_pShellView;
	return S_OK;
}

STDMETHODIMP CShellBrowser::RemoveMenusSB(HMENU hmenuShared)
{
	OutputDebugString(L"CShellBrowser::RemoveMenusSB\n");
	return E_NOTIMPL;
}

STDMETHODIMP CShellBrowser::SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret)
{
	OutputDebugString(L"CShellBrowser::SendControlMsg\n");
	if (pret == NULL)
		return E_POINTER;
	if (FCW_STATUS == id || FCW_TREE == id)
	{
		*pret = ::SendMessage(m_MainWnd, uMsg, wParam, lParam);
		return S_OK;
	}
	return E_NOTIMPL;
}

STDMETHODIMP CShellBrowser::SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject)
{
	OutputDebugString(L"CShellBrowser::SetMenuSB\n");
	//MessageBox(0, L"CShellBrowser::SetMenuSB", 0, 0);
	return E_NOTIMPL;
}

STDMETHODIMP CShellBrowser::SetStatusTextSB(LPCWSTR lpszStatusText)
{
	OutputDebugString(L"CShellBrowser::SetStatusTextSB\n");
	return E_NOTIMPL;
}

STDMETHODIMP CShellBrowser::SetToolbarItems(LPTBBUTTONSB lpButtons, UINT nButtons, UINT uFlags)
{
	OutputDebugString(L"CShellBrowser::SetToolbarItems\n");
	return E_NOTIMPL;
}

STDMETHODIMP CShellBrowser::TranslateAcceleratorSB(LPMSG lpmsg, WORD wID)
{
	OutputDebugString(L"CShellBrowser::TranslateAcceleratorSB\n");
	return S_OK;
}